package cn.sdormitory.basedata.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.sdormitory.basedata.dao.BClassDao;
import cn.sdormitory.basedata.dao.BStudentDao;
import cn.sdormitory.basedata.dao.ClassDeviceDao;
import cn.sdormitory.basedata.entity.BClass;
import cn.sdormitory.basedata.service.BClassService;
import cn.sdormitory.basedata.vo.*;
import cn.sdormitory.common.IdAndName;
import cn.sdormitory.common.constant.CommonConstant;
import cn.sdormitory.common.utils.ContainerUtil;
import cn.sdormitory.smartdor.dao.SdAttenceDao;
import cn.sdormitory.smartdor.dao.SdHygieneDao;
import cn.sdormitory.smartdor.vo.SdHygieneVo;
import cn.sdormitory.sys.dao.SysUserDao;
import cn.sdormitory.sys.entity.SysUser;
import cn.sdormitory.sys.service.SysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @创建人：zhouyang
 * @创建时间：2020/11/2 17:20
 * @version：V1.0
 */
@Slf4j
@Service("bClassService")
public class BClassServiceImpl extends ServiceImpl<BClassDao, BClass> implements BClassService {
    @Resource
    private BClassDao bClassDao;
    @Resource
    private SysUserDao sysUserDao;
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    BStudentDao bStudentDao;
    @Resource
    ClassDeviceDao classDeviceDao;

    @Resource
    private SdHygieneDao sdHygieneDao;

    @Resource
    private SdAttenceDao sdAttenceDao;
    @Autowired
    private PasswordEncoder passwordEncoder;

    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public List<IdAndName<Long>> getIdAndNames() {
        List<BClass> list = list(Wrappers.lambdaQuery(BClass.class)
                .select(BClass::getId, BClass::getClassName)
                .eq(BClass::getStatus, 1)
        );
        return ContainerUtil.mapList(list, item->IdAndName.generate(item.getId(),item.getClassName()));
    }

    @Override
    public IPage<BClass> getPage(Map<String, Object> params) {
        int pageSize = Integer.parseInt(String.valueOf(params.get("pageSize")));
        int pageNum = Integer.parseInt(String.valueOf(params.get("pageNum")));

        String className = (String) params.get("className");
        String status = (String) params.get("status");
        String classTeacherName = (String) params.get("classTeacherName");
        String classDept = (String) params.get("classDept");

        LambdaQueryWrapper<BClass> wrapper = new LambdaQueryWrapper<>();

        if (StrUtil.isNotEmpty(className)) {
            wrapper.eq(BClass::getClassName, className);
        }
        if (StrUtil.isNotEmpty(status)) {
            wrapper.eq(BClass::getStatus, status);
        }
        if (StrUtil.isNotEmpty(classDept)) {
            wrapper.eq(BClass::getClassDept, classDept);
        }
        if(StrUtil.isNotEmpty(classTeacherName)){
            SysUser sysUser=sysUserService.getByUserName(classTeacherName);
            if(sysUser != null){
                wrapper.eq(BClass::getClassTeacherId, sysUser.getId());
            }
        }

        wrapper.apply(params.get(CommonConstant.SQL_FILTER) != null, (String) params.get(CommonConstant.SQL_FILTER));
        return page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    public BClass getBClassById(Long id) {
        return getById(id);
    }

    @Override
    public int create(BClass bClass) {
        return this.baseMapper.insert(bClass);
    }

    @Override
    public int delete(Long id) {
        return this.baseMapper.deleteById(id);
    }

    @Override
    public int update(Long id, BClass bClass) {
        bClass.setId(id);
        bClass.setModifyTime(new Date());
        return this.baseMapper.updateById(bClass);
    }

    @Override
    public int deleteByIds(Long[] ids) {
        return this.baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    @Override
    public int updateStatus(Long id, String status) {
        BClass bClass = new BClass();
        bClass.setId(id);
        bClass.setStatus(status);
        return this.baseMapper.updateById(bClass);
    }

    @Override
    public BClass getByClassName(String className) {
        return this.baseMapper.selectOne(new LambdaQueryWrapper<BClass>().eq(BClass::getClassName, className));
    }

    @Override
    public List<BClass> getListAll() {
        return list(new LambdaQueryWrapper<BClass>().eq(BClass::getStatus,CommonConstant.VALID_STATUS));
    }

    @Override
    public List<BClass> getBClassList(String className,String status,String classTeacherName,String classDept,String classType, int pageNum,int pageSize) {
        int currIndex=(pageNum-1)*pageSize;
        return bClassDao.getBClassList(className,status,classTeacherName,classDept,classType,currIndex,pageSize);
    }

    @Override
    public List<BClass> listClassByTeacher(Long classTeacherId) {
        LambdaQueryWrapper<BClass> wrapper = getListClassByTeacherWrapper(classTeacherId);
        return list(wrapper);
    }

    @Override
    public List<Long> listClassIdsByTeacher(Long classTeacherId) {
        LambdaQueryWrapper<BClass> wrapper = getListClassByTeacherWrapper(classTeacherId);
        wrapper.select(BClass::getId);
        return listObjs(wrapper, Convert::toLong);
    }

    private static @NotNull LambdaQueryWrapper<BClass> getListClassByTeacherWrapper(Long classTeacherId) {
        LambdaQueryWrapper<BClass> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BClass::getStatus, CommonConstant.VALID_STATUS);
        wrapper.eq(BClass::getClassTeacherId, classTeacherId);
        return wrapper;
    }

    @Override
    public List<BClassDorAndHyVo> getClassDorAndHyListByTeaId(Long classTeacherId,String checkDate) {
        List<BClassDorAndHyVo> classDorAndHyList = bClassDao.getClassDorAndHyListByTeaId(classTeacherId);
        if(checkDate == null||checkDate == ""){
            checkDate = simpleDateFormat.format(new Date());
        }
        for(BClassDorAndHyVo vo : classDorAndHyList) {
            String bdormitoryId = vo.getBdormitoryId();
            String attenceInfo = "";
            String hygieneInfo = "";
            if (null != bdormitoryId) {
                String[] bdormitoryIdArray = bdormitoryId.split(",");
                for (String dormitoryId : bdormitoryIdArray) {
                    // 根据宿舍ID 查询考勤信息
                    AttenceVo attenceVo = sdAttenceDao.getAttenceBySdormitoryid(Long.valueOf(dormitoryId), checkDate);
                    attenceInfo += attenceVo.getRoomName() + "：考勤情况 </br>";
                    hygieneInfo += attenceVo.getRoomName() + "：卫生情况 </br>";

                    if(attenceVo!=null){
                        attenceInfo += " &nbsp;&nbsp;&nbsp; 正常：" + attenceVo.getNormal() + " 未归寝：" + attenceVo.getAbsence() + "   请假：" + attenceVo.getLeaveCount() + "</br>";
                    }else{
                        attenceInfo += " &nbsp;&nbsp;&nbsp; 未考勤 </br>";
                    }
                    // 根据宿舍ID 查询卫生信息
                    SdHygieneVo sdHygieneVo = sdHygieneDao.getAppHygieneByBIdAndDate(Long.valueOf(dormitoryId), checkDate);
                    if(sdHygieneVo!=null){
                        hygieneInfo += "&nbsp;&nbsp;&nbsp;"+sdHygieneVo.getGrade();
                    }else{
                        hygieneInfo += " &nbsp;&nbsp;&nbsp; 未检查 </br>";
                    }

                }

            }
            vo.setAttenceInfo(attenceInfo);
            vo.setHygieneInfo(hygieneInfo);
        }
        return classDorAndHyList;
    }

    @Override
    public Long getStuCountByClaId(Long classId) {
        return bClassDao.getStuCountByClaId(classId);
    }
    @Override
    public List<BStudentLeaveCountVo> countByClassIdWithDate(int id, String startDate, String endDate, int index, int size) {
        index=(index-1)*size;
        return bStudentDao.getStudentLeaveCountByClassId(id,startDate,endDate,index,size);
    }
    @Override
    public String getClassIdByClassName(String className) {
        return bClassDao.getClassIdByClassName(className);
    }
    @Override
    public String getClassTotalCount(int id, String startDate, String endDate){
        return bStudentDao.getStudentLeaveTotalCount(id,startDate,endDate);
    }
    @Override
    public List<BStudentLeaveListVo> getStudentLeaveAllList(String studentNo, String studentName, String startDate, String endDate, int classId,int index,int size){
        index=(index-1)*size;
        return classDeviceDao.getStudentLeaveAllList(studentNo,studentName,startDate,endDate,classId,index, size);
    }
    @Override
    public List<BStudentLeaveListVo> getStudentLeaveStuList(String studentNo, String studentName, String startDate, String endDate, int classId,int index,int size){
        index=(index-1)*size;
        return classDeviceDao.getStudentLeaveStuList(studentNo,studentName,startDate,endDate,classId, index,size);
    }
    @Override
    public List<BStudentLeaveListVo> getStudentLeaveSdList(String studentNo, String studentName, String startDate, String endDate, int classId,int index,int size){
        index=(index-1)*size;
        return classDeviceDao.getStudentLeaveSdList(studentNo,studentName,startDate,endDate,classId, index, size);
    }
    @Override
    public String getStudentLeaveAllCount(String studentNo, String studentName, String startDate, String endDate, int classId){
        return classDeviceDao.getStudentLeaveAllCount(studentNo,studentName,startDate,endDate,classId);
    }

    @Override
    public List<ClassDeptGroupVo> getBClassListByDeptGroup() {
        List<BClassVo> classList = Optional.ofNullable(bClassDao.getBClassListByDeptGroup()).orElse(Collections.emptyList());

        return classList.stream()
                .collect(Collectors.groupingBy(BClassVo::getDeptName))
                .entrySet().stream()
                .map(entry -> {
                    ClassDeptGroupVo deptGroupVo = new ClassDeptGroupVo();
                    deptGroupVo.setDeptName(entry.getKey());
                    deptGroupVo.setClassList(entry.getValue());
                    return deptGroupVo;
                })
                .collect(Collectors.toList());
    }

}
